package com.leetcode.partition18;

import java.io.*;
import java.util.*;

/**
 * @author `RKC`
 * @date 2022/2/2 10:04
 */
@SuppressWarnings("all")
public class LC1724检查边长度限制的路径是否存在II {

    private static final int N = (int) (2e4 + 10), M = 2 * N, D = (int) (Math.log(N) / Math.log(2));
    private static int[] h = new int[N], e = new int[M], ne = new int[M], w = new int[M];

    //maxw[i][j]表示节点i朝当前连通块的根节点方向跳2^j步之间最大的边权
    private static int[][] f = new int[N][D + 1], maxw = new int[N][D + 1], edges;
    private static int[] depth = new int[N], parent = new int[N];
    private static int n = 0, idx = 1;
    private static Queue<Integer> q = new ArrayDeque<>(N);
    private static boolean[] st = new boolean[N];

    private static final BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    private static final BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(System.out));

    public static void main(String[] args) throws IOException {
        String[] ss = reader.readLine().split(" ");
        //读入节点数量、边数量、询问次数
        int n = Integer.parseInt(ss[0]), m = Integer.parseInt(ss[1]), que = Integer.parseInt(ss[2]);
        int[][] edges = new int[m][3];
        //读入边<u, v, w>
        for (int i = 0; i < m; i++) {
            ss = reader.readLine().split(" ");
            int a = Integer.parseInt(ss[0]), b = Integer.parseInt(ss[1]), c = Integer.parseInt(ss[2]);
            edges[i] = new int[]{a, b, c};
        }
        distanceLimitedPathsExist(n, edges);
        while (que-- > 0) {
            //询问，读入节点p、q和限制距离
            ss = reader.readLine().split(" ");
            int p = Integer.parseInt(ss[0]), q = Integer.parseInt(ss[1]), limit = Integer.parseInt(ss[2]);
            writer.write(query(p, q, limit) + "\n");
            writer.flush();
        }
        writer.flush();
    }

    public static void distanceLimitedPathsExist(int n, int[][] edgeList) {
        edges = edgeList;
        kruskal();
        //初始化lca需要的数组
        for (int i = 0; i < n; i++) {
            if (st[i]) continue;
            bfs(i);
        }
    }

    public static boolean query(int p, int q, int limit) {
        //判断p和q是否在一个连通分量中，如果不在，直接返回false
        if (find(p) != find(q)) return false;
        return lca(p, q, limit);
    }

    private static void kruskal() {
        //初始化并查集并排序所有边
        for (int i = 0; i < N; i++) parent[i] = i;
        Arrays.sort(edges, 0, edges.length, (o1, o2) -> Integer.compare(o1[2], o2[2]));
        for (int i = 0; i < edges.length; i++) {
            int a = edges[i][0], b = edges[i][1], c = edges[i][2];
            int x = find(a), y = find(b);
            if (x != y) {
                parent[x] = y;
                //MST建图
                add(a, b, c);
                add(b, a, c);
            }
        }
    }

    private static boolean lca(int x, int y, int limit) {
        if (depth[x] < depth[y]) {
            int t = x;
            x = y;
            y = t;
        }
        for (int i = D; i >= 0; i--) {
            if (depth[f[x][i]] >= depth[y]) {
                //跳的过程中不能出现大于等于limit的最大边
                if (maxw[x][i] >= limit) return false;
                x = f[x][i];
            }
        }
        if (x == y) return true;
        for (int i = D; i >= 0; i--) {
            if (f[x][i] != f[y][i]) {
                if (maxw[x][i] >= limit || maxw[y][i] >= limit) return false;
                x = f[x][i];
                y = f[y][i];
            }
        }
        if (maxw[x][0] >= limit || maxw[y][0] >= limit) return false;
        return true;
    }

    private static void bfs(int root) {
        depth[root] = 1;
        f[root][0] = root;
        q.add(root);
        while (!q.isEmpty()) {
            int u = q.poll();
            st[u] = true;
            for (int i = h[u]; i != 0; i = ne[i]) {
                int v = e[i];
                if (depth[v] != 0) continue;
                depth[v] = depth[u] + 1;
                maxw[v][0] = w[i];
                f[v][0] = u;
                for (int j = 1; j <= D; j++) {
                    int anc = f[v][j - 1];
                    f[v][j] = f[anc][j - 1];
                    maxw[v][j] = Math.max(maxw[v][j], Math.max(maxw[v][j - 1], maxw[anc][j - 1]));
                }
                q.add(v);
            }
        }
    }

    private static int find(int x) {
        if (x == parent[x]) return x;
        return parent[x] = find(parent[x]);
    }

    private static void add(int a, int b, int c) {
        e[idx] = b;
        ne[idx] = h[a];
        h[a] = idx;
        w[idx++] = c;
    }
}
